﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StreetlightGames.XnaEngine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using StreetlightGames.SpaceShooter.Patterns;
using Microsoft.Xna.Framework.Graphics;
using System.Runtime.Serialization;
using StreetlightGames.XnaEngine.Particles;

namespace StreetlightGames.SpaceShooter.Enemies
{
    public class EnemyShip : ModelObject
    {
        /// <summary>Gets or sets the Speed value</summary>
        public float Speed
        {
            get { return _speed; }
            set { _speed = value; }
        }
        private float _speed = 1000;

        /// <summary>Gets or sets the Target value</summary>
        public Vector3 Target
        {
            get { return _target; }
            set { _target = value; }
        }
        private Vector3 _target;

        /// <summary>Gets the SpaceShooterGame value</summary>
        public SpaceShooterGame SpaceShooterGame
        {
            get { return Game as SpaceShooterGame; }
        }
        
        /// <summary>Gets or sets the Heading value</summary>
        public float Heading
        {
            get
            {
                if (Velocity == Vector3.Zero)
                {
                    return 0;
                }
                return (float)Math.Atan2(-Velocity.Z, Velocity.X) - MathHelper.PiOver2;
            }
            set
            {
                double angle = (double)value + MathHelper.PiOver2;
                Velocity = new Vector3((float)((double)Speed * Math.Cos(angle)), 0, -(float)((double)Speed * Math.Sin(angle)));
            }
        }

        /// <summary>Gets or sets the Pattern value</summary>
        public Patterns.Pattern Pattern
        {
            get { return _pattern; }
            set
            {
                _pattern = value;
                if (_pattern != null)
                {
                    _pattern.Ship = this;
                }
            }
        }
        private Patterns.Pattern _pattern;

        /// <summary>Gets or sets the Wave value</summary>
        public Wave Wave
        {
            get { return _wave; }
            set { _wave = value; }
        }
        private Wave _wave;

        /// <summary>Gets or sets the StartDelay value</summary>
        public double StartDelay
        {
            get { return _startDelay; }
            set { _startDelay = value; }
        }
        private double _startDelay;

        /// <summary>Gets or sets the IsStarted value</summary>
        public bool IsStarted
        {
            get { return _isStarted; }
            set { _isStarted = value; }
        }
        private bool _isStarted;

        /// <summary>Gets or sets the IsArmed value</summary>
        public bool IsArmed
        {
            get { return _isArmed; }
            set { _isArmed = value; }
        }
        private bool _isArmed;

        /// <summary>Gets the Missiles value</summary>
        public List<Missile> Missiles
        {
            get { return _missiles; }
        }
        private List<Missile> _missiles = new List<Missile>();

        public override ICamera Camera
        {
            get
            {
                return base.Camera;
            }
            set
            {
                base.Camera = value;
                foreach (Missile missile in Missiles)
                {
                    missile.Camera = value;
                }
            }
        }

        private double _timeSinceLastFire;
        private double _fireDelay;

        public EnemyShip(Game game)
            : base(game)
        {
            Scale = 10;
            _fireDelay = 0.2;
        }

        public override void Initialize()
        {
            if (Missiles.Count == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    Missile missile = new Missile(Game);
                    missile.Camera = Camera;
                    _missiles.Add(missile);
                    Game.Components.Add(missile);
                }
            }
            base.Initialize();
        }


        public override void Update(GameTime gameTime)
        {
            if (IsAlive)
            {
                if (Pattern != null)
                {
                    Pattern.Update(gameTime);
                }
                if (IsArmed)
                {
                    _timeSinceLastFire += gameTime.ElapsedGameTime.TotalSeconds;
                    if (_timeSinceLastFire > _fireDelay)
                    {
                        FireMissile();
                    }
                }
                Rotation = new Vector3(0, Heading, 0);
                base.Update(gameTime);
                if (Position.X < -1200 || Position.X > 1200 || Position.Z < -2000 || Position.Z > 400)
                {
                    IsAlive = false;
                }
            }
        }

        public override void Draw(GameTime gameTime)
        {
            if (IsAlive)
            {
                base.Draw(gameTime);
            }
        }

        public virtual void Start()
        {
            IsAlive = true;
            IsStarted = true;
            SetFireDelay();
        }

        private void SetFireDelay()
        {
            _fireDelay = RandomHelper.NextDouble(1, 5);
        }

        public void FireMissile()
        {
            foreach (Missile missile in _missiles)
            {
                if (!missile.IsAlive)
                {
                    missile.Position = Position;
                    missile.Launch();
                    missile.Rotation = new Vector3(0, MathHelper.Pi, 0);
                    missile.Velocity = new Vector3(missile.Velocity.X, missile.Velocity.Y, -missile.Velocity.Z);
                    missile.Velocity += new Vector3(Velocity.X, 0, 0);
                    _timeSinceLastFire = 0;
                    _fireDelay = 0.2;
                    return;
                }
                SetFireDelay();
            }
        }

        internal virtual void Explode()
        {
            IsAlive = false;
            AudioController.Instance.PlayCue("Explosion");
            for (int i = 0; i < 100; i++)
            {
                SpaceShooterGame.ExplosionSystem.AddParticle(Position, Velocity);
            }
        }

        public void AddPattern(Pattern pattern)
        {
            if (Pattern == null)
            {
                Pattern = pattern;
            }
            else
            {
                Pattern nextPattern = Pattern;
                while (nextPattern.NextPattern != null)
                {
                    nextPattern = nextPattern.NextPattern;
                }
                nextPattern.NextPattern = pattern;
            }
        }

        internal int CalculateScore(PlayerShip playerShip)
        {
            Vector3 relativeVelocity = Velocity - playerShip.Velocity;
            Vector3 delta = Position - playerShip.Position;
            int score = ((int)relativeVelocity.Length() + (int)delta.Length()) / 100 * 10;
            if (score == 0)
            {
                return 1;
            }
            return score;
        }
    }
}
